{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#  Workarounds for the problem using grid equivalents\n",
    "This tutorial gives some suggestions to solve the difficulties that arise when using grid equivalent.\n",
    "In this tutorial, we still use the grid case9 as the test bed:\n",
    "\n",
    "- internal area (buses): [0, 3, 4, 8]\n",
    "- boundary buses: [4, 8] (boundary buses belong to the internal area)\n",
    "- external area (buses): [1, 2, 5, 6, 7] \n",
    "\n",
    "<img src=\"pics/grid areas.png\" alt=\"ALT\">"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:16:11.696508Z",
     "start_time": "2025-10-20T06:16:07.329993Z"
    }
   },
   "outputs": [],
   "source": [
    "from pandapower.networks.power_system_test_cases import case9\n",
    "from pandapower.grid_equivalents import get_equivalent\n",
    "from pandapower.create import create_dcline\n",
    "from pandapower.run import runpp\n",
    "from copy import deepcopy\n",
    "\n",
    "net = case9()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## A) dc line\n",
    "\n",
    "If the to-be-reduced grid has dc-lines. We need convert them before starting grid equivalent. First of all, let's create a dc-line. In the following, the line (index=2) between bus 4 and bus 8 is replaced by a dc-line"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:16:13.722393Z",
     "start_time": "2025-10-20T06:16:11.701736Z"
    }
   },
   "outputs": [],
   "source": [
    "net.line.drop([2],inplace=True)\n",
    "create_dcline(net, 4, 5, 50, 0.5, 0.7, 1.0, 1.0)\n",
    "runpp(net)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, we have got a grid with dc-line (see A)).\n",
    "<img src=\"pics/grid areas (workarounds).png\" alt=\"ALT\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "using *_add_dcline_gens* the dc-lines are represented by generators. Then, we need to remote or disconnect the origin dc_line or close them. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:16:13.785588Z",
     "start_time": "2025-10-20T06:16:13.727402Z"
    }
   },
   "outputs": [],
   "source": [
    "from pandapower.auxiliary import _add_dcline_gens\n",
    "net2 = deepcopy(net)\n",
    "_add_dcline_gens(net2)\n",
    "net2.dcline.in_service=False\n",
    "runpp(net2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can compare the power flow results between *net1* and *net2* and carry out the grid equivalent process."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:16:15.204604Z",
     "start_time": "2025-10-20T06:16:13.791573Z"
    }
   },
   "outputs": [],
   "source": [
    "print(\"net with dcline\", net.res_bus)\n",
    "print(\"net with represented dcline\", net2.res_bus)\n",
    "net_eq = get_equivalent(net2, \"rei\", [4,8], [0])\n",
    "print(\"equivalent net\", net_eq.res_bus)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## B) slack in the external area\n",
    "\n",
    "In some cases, there are slack buses in the external area, see B). It could cause power flow problems during the grid equivalent calculation. In this case, we can consider the slack buses as the boundary to reserve them.\n",
    "In the grid *case9*, there are two generators in the external area. We activate their slack function and treat the corresponding buses as the boundary."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:16:16.734360Z",
     "start_time": "2025-10-20T06:16:15.211846Z"
    }
   },
   "outputs": [],
   "source": [
    "net = case9()\n",
    "net.gen.slack = True\n",
    "runpp(net)\n",
    "boundary_buses = [4, 8, 1, 2]\n",
    "net_eq = get_equivalent(net, \"rei\", [4,8], [0])\n",
    "print(\"original net\", net.res_bus)\n",
    "print(\"equivalent net\", net_eq.res_bus)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
